<template>
  <div class="app-container">
    <!-- 主页 -->
    <div v-show="!detailedPageVisible">

      <!-- 设备搜索 -->
      <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">

        <!-- 根据设备id搜索 -->
        <el-form-item label="设备ID" prop="id">
          <el-input
            v-model="queryParams.id"
            placeholder="请输入设备ID"
            clearable
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>

        <!-- 根据设备名称搜索 -->
        <el-form-item label="设备名称" prop="deviceName">
          <el-input
            v-model="queryParams.deviceName"
            placeholder="请输入设备名称"
            clearable
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>

        <!-- 根据所属产品搜索 -->
        <el-form-item label="所属产品" prop="productId">
          <el-select v-model="queryParams.productId" placeholder="请选择所属产品" clearable>
            <el-option
              v-for="product in productMap"
              :key="product[0]"
              :label="product[1].productName"
              :value="product[0]"
            />
          </el-select>
        </el-form-item>

        <!-- 根据设备状态搜索 -->
        <el-form-item label="设备状态" prop="deviceState">
          <el-select v-model="queryParams.deviceState" placeholder="请选择设备状态" clearable>
            <el-option
              v-for="dict in dict.type.iot_device_state"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>

        <!-- 根据设备类型搜索 -->
        <el-form-item label="设备类型" prop="deviceType">
          <el-select v-model="queryParams.deviceType" placeholder="请选择设备类型" clearable>
            <el-option
              v-for="dict in dict.type.iot_product_device_type"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>

        <!-- 搜索操作：搜索、重置 -->
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
        </el-form-item>

      </el-form>

      <!-- 操作区域 -->
      <el-row :gutter="10" class="mb8">

        <!-- 新增设备 -->
        <el-col :span="1.5">
          <el-button
            type="primary"
            plain
            icon="el-icon-plus"
            size="mini"
            @click="handleAdd"
            v-hasPermi="['iot:device:add']"
          >新增
          </el-button>
        </el-col>

        <!-- 删除设备 -->
        <el-col :span="1.5">
          <el-button
            type="danger"
            plain
            icon="el-icon-delete"
            size="mini"
            :disabled="multiple"
            @click="handleDelete"
            v-hasPermi="['iot:device:remove']"
          >删除
          </el-button>
        </el-col>

        <!-- 导出设备 -->
        <el-col :span="1.5">
          <el-button
            type="warning"
            plain
            icon="el-icon-download"
            size="mini"
            @click="handleExport"
            v-hasPermi="['iot:device:export']"
          >导出
          </el-button>
        </el-col>

        <!-- 导入设备 -->
        <el-col :span="1.5">
          <el-button
            type="danger"
            plain
            icon="el-icon-upload2"
            size="mini"
            @click="handleImport"
            v-hasPermi="['iot:device:import']"
          >导入
          </el-button>
        </el-col>

        <!-- 激活设备 -->
        <el-col :span="1.5">
          <el-button
            type="success"
            plain
            icon="el-icon-finished"
            size="mini"
            @click="batchDeployDevice"
            v-hasPermi="['iot:device:edit']"
          >激活
          </el-button>
        </el-col>

        <!-- 同步设备状态 -->
        <el-col :span="3">
          <el-button
            type="primary"
            plain
            icon="el-icon-refresh"
            size="mini"
            @click="handleSyncDeviceState"
            v-hasPermi="['iot:device:edit']"
          >同步状态
          </el-button>
        </el-col>

        <!-- 设备状态数量统计 -->
        <!-- 设备总数 -->
        <el-col :span="3">
          <span class="device-state">全部设备&emsp;</span>
          <span>{{ this.count.amount }}</span>
        </el-col>

        <!-- 设备在线数量 -->
        <el-col :span="3">
          <svg-icon style="color: #45c904" icon-class="dot"/>
          <span class="device-state">在线&emsp;</span>
          <span>{{ this.count.onlineCount }}</span>
        </el-col>

        <!-- 设备离线数量 -->
        <el-col :span="3">
          <svg-icon style="color: red" icon-class="dot"/>
          <span class="device-state">离线&emsp;</span>
          <span>{{ this.count.offlineCount }}</span>
        </el-col>

        <!-- 设备未激活数量 -->
        <el-col :span="1.5">
          <svg-icon style="color: #1890ff" icon-class="dot"/>
          <span class="device-state">未激活&emsp;</span>
          <span>{{ this.count.notActiveCount }}</span>
        </el-col>

        <!-- 工具栏：隐藏显示搜索按钮、刷新按钮 -->
        <right-toolbar :showSearch.sync="showSearch" @queryTable="resetQuery"></right-toolbar>

      </el-row>

      <!-- 设备列表 -->
      <el-table ref="deviceTable" v-loading="loading" :data="deviceList" @selection-change="handleSelectionChange">

        <el-table-column type="selection" width="55" align="center"/>

        <el-table-column label="设备ID" align="center" prop="id"/>

        <el-table-column label="设备名称" align="center" prop="deviceName"/>

        <el-table-column prop="productId" label="产品名称" header-align="center" align="center">
          <template slot-scope="scope">
            {{ (productMap.get(scope.row.productId) || {}).productName }}
          </template>
        </el-table-column>

        <el-table-column prop="deviceType" label="设备类型" header-align="center" align="center">
          <template slot-scope="scope">
            <dict-tag :options="dict.type.iot_product_device_type" :value="getTableDeviceType(scope.row)"/>
          </template>
        </el-table-column>

        <el-table-column label="注册日期" sortable align="center" prop="registryTime"/>

        <el-table-column label="状态" align="center" prop="deviceState">
          <template slot-scope="scope">
            <dict-tag :options="dict.type.iot_device_state" :value="scope.row.deviceState"/>
          </template>
        </el-table-column>

        <el-table-column label="描述" align="center" prop="description"/>

        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">

          <template slot-scope="scope">

            <el-button
              size="mini"
              type="text"
              icon="el-icon-search"
              @click="handleCheck(scope.row)"
              v-hasPermi="['iot:device:list']"
            >查看
            </el-button>

            <el-button
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click="handleUpdate(scope.row)"
              v-hasPermi="['iot:device:edit']"
            >修改
            </el-button>

            <el-button
              v-if="scope.row.deviceState === 'notActive'"
              size="mini"
              type="text"
              icon="el-icon-delete"
              @click="handleDelete(scope.row)"
              v-hasPermi="['iot:device:remove']"
            >删除
            </el-button>

            <el-button
              v-if="scope.row.deviceState === 'notActive'"
              size="mini"
              type="text"
              icon="el-icon-switch-button"
              @click="handleEnableDisableStateChange(scope.row)"
              v-hasPermi="['iot:device:remove']"
            >启用
            </el-button>

            <el-button
              v-if="scope.row.deviceState !== 'notActive'"
              size="mini"
              type="text"
              icon="el-icon-circle-close"
              @click="handleEnableDisableStateChange(scope.row)"
              v-hasPermi="['iot:protocol:remove']"
            >禁用
            </el-button>

          </template>

        </el-table-column>

      </el-table>

      <!-- 表格分页 -->
      <pagination
        v-show="total>0"
        :total="total"
        :page.sync="queryParams.pageNum"
        :limit.sync="queryParams.pageSize"
        @pagination="getList"
      />

    </div>

    <!--设备出对话框-->
    <device-export ref="deviceExport"/>

    <!--设备导入对话框-->
    <device-import ref="deviceImport" @update="handleRefresh"/>

    <!-- 添加或修改设备对话框 -->
    <device-add-edit ref="deviceAddEdit" @update="handleRefresh"/>

    <!-- 详情页 -->
    <device-detailed/>

  </div>
</template>

<script>
import {
  listDevice,
  delDevice,
  deployDevice,
  undeployDevice,
  deployAllDevice,
  syncDeviceState,
  syncAllDeviceState,
  getDeviceCount
} from '@/api/iot/device'
import DeviceAddEdit from '@/views/iot/device/deviceAddEdit'
import DeviceExport from '@/views/iot/device/deviceExport'
import DeviceImport from '@/views/iot/device/deviceImport'
import { queryProduct } from '@/api/iot/product'
import DeviceDetailed from './deviceDetailed'
import { mapState } from 'vuex'

export default {
  name: 'Device',
  components: {
    DeviceExport,
    DeviceImport,
    DeviceAddEdit,
    DeviceDetailed
  },
  dicts: [
    // 设备状态
    'iot_device_state',
    //设备类型
    'iot_product_device_type'
  ],
  data() {
    return {
      //统计设备状态数据对象
      count: {
        amount: null,
        offlineCount: null,
        onlineCount: null,
        notActiveCount: null
      },
      // 设备表格数据
      deviceList: [],
      //产品列表
      productMap: new Map(),
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 弹出层标题
      title: '',
      // 是否显示弹出层
      open: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        id: null,
        deviceName: null,
        publishState: null,
        productId: null,
        deviceState: null,
        deviceType: null
      }
    }
  },
  computed: {
    ...mapState({
      detailedPageVisible: state => state.device.detailedPageVisible,
      deviceDetailInfo: state => state.device.deviceDetailInfo,
      routeValue() { return this.$route.query }
    })
  },
  watch: {
    detailedPageVisible(visible) {
      if (!visible) {
        this.getList()
      }
    },
    // 监听路由数据
    routeValue: {
      immediate: true,
      handler(params) {
        const productId = params.productId
        if (productId) {
          this.queryParams.productId = productId
          this.getList()
        }
        // 关闭设备详情页面
        this.$store.commit("DEVICE_DETAILED_PAGE_VISIBLE", false);
      }
    }
  },
  created() {
    // 刷新操作
    this.handleRefresh()
    // 获取产品信息
    this.getProducts()
    // 订阅设备状态（在线）实时数据
    this.subDeviceOnlineMessageAll()
    // 订阅设备状态（离线）实时数据
    this.subDeviceOfflineMessageAll()
  },
  destroyed() {
    // 销毁页面的时候还原数据
    this.$store.commit('DEVICE_DETAILED_PAGE_VISIBLE', false)

    // 取消设备状态（在线）实时数据订阅
    this.unsubDeviceOnlineMessageAll()

    // 取消设备状态（离线）实时数据订阅
    this.unsubDeviceOfflineMessageAll()
  },
  methods: {
    //启动全部设备点击事件
    batchDeployDevice() {

      const ids = this.ids

      if (ids && ids.length > 0) {
        this.$modal
          .confirm('确定要启用选中的设备?')
          .then(() => {
            deployDevice(ids).then(() => {
              this.handleRefresh()
            })
          })
        return
      }

      this.$modal
        .confirm('确定启用全部设备？')
        .then(() => {
          deployAllDevice().then(() => {
            this.handleRefresh()
          })
        })
    },
    // 同步设备状态
    handleSyncDeviceState() {

      const ids = this.ids
      if (ids && ids.length > 0) {
        this.$modal
          .confirm('确定要同步选中的设备状态?')
          .then(() => {
            syncDeviceState(ids).then(({ data }) => {
              this.$modal.msgSuccess(`已完成，总数量:${data}`)
              this.handleRefresh()
            })
          })
        return
      }

      this.$modal
        .confirm('确定同步全部设备状态?')
        .then(() => {
          syncAllDeviceState().then(({ data }) => {
            this.$modal.msgSuccess(`已完成，总数量:${data}`)
            this.handleRefresh()
          })
        })
    },
    // 查看按钮的点击事件
    handleCheck(row) {
      // 隐藏主页面显示详情页
      this.$store.commit('DEVICE_DETAILED_PAGE_VISIBLE', true)
      // 传递数据给详情页面
      this.$store.commit('DEVICE_ID', row.id)

    },
    /** 获取表格设备类型数据 */
    getTableDeviceType(row) {
      return row.deviceType = (this.productMap.get(row.productId) || {}).deviceType
    },
    /** 查询设备列表 */
    getList() {
      this.loading = true
      listDevice(this.queryParams).then(response => {
        this.deviceList = response.rows
        this.total = response.total
        this.count.amount = response.total
        this.loading = false
      })
    },

    /** 刷新操作 */
    handleRefresh() {
      // 更新表格
      this.getList()
      // 更新离线数
      this.updateOfflineCount()
      // 更新在线数
      this.updateOnlineCount()
      // 更新未激活设备数据量
      this.updateNotActiveCount()
    },

    /** 更新离线设备数数*/
    updateOfflineCount() {
      // 离线设备数量
      getDeviceCount({ deviceState: 'offline' }).then(({ data }) => {
        this.count.offlineCount = data
      })
    },
    /** 更新在线设备数据量*/
    updateOnlineCount() {
      // 在线设备数量
      getDeviceCount({ deviceState: 'online' }).then(({ data }) => {
        this.count.onlineCount = data
      })
    },
    /** 更新未激活设备数据量*/
    updateNotActiveCount() {
      // 未激活设备数据量
      getDeviceCount({ deviceState: 'notActive' }).then(({ data }) => {
        this.count.notActiveCount = data
      })
    },

    /** 获取产品信息 */
    getProducts() {
      // 已发布的产品
      queryProduct().then(({ data }) => {
        let map = new Map();
        (data || []).forEach(item => {
          map.set(item.id, item)
        })
        this.productMap = map
      })
    },

    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },

    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm('queryForm')
      this.queryParams.productId = undefined
      this.handleQuery()
    },

    /** 多选框选中数据 */
    handleSelectionChange(selection) {
      selection.forEach(row => {
        if (row.publishState === 1) {
          this.$refs.deviceTable.toggleRowSelection(row)
        }
      })
      this.ids = selection.map(item => item.id)
      this.single = selection.length !== 1
      this.multiple = !selection.length
    },

    /** 新增按钮操作 */
    handleAdd() {
      this.$refs.deviceAddEdit.handleAdd()
    },

    /** 修改按钮操作 */
    handleUpdate(row) {
      const id = row.id || this.ids[0]
      this.$refs.deviceAddEdit.handleUpdate(id)
    },

    /** 批量导入按钮操作 */
    handleImport() {
      this.$refs.deviceImport.handleImport()
    },

    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids
      this.$modal
        .confirm('是否确认删除设备ID为"' + ids + '"的设备？')
        .then(() => {
          return delDevice(ids).then(({ code }) => {
            if (code === 200) {
              this.handleRefresh()
              this.$modal.msgSuccess('删除成功')
            }
          })
        })
    },

    /** 导出按钮操作 */
    handleExport() {
      this.$refs.deviceExport.handleExport(this.productMap)
    },

    /**
     * 启用禁用状态修改
     */
    handleEnableDisableStateChange(row) {
      let text = row.deviceState === 'notActive' ? '启用' : '禁用'
      this.$modal
        .confirm(`确认要${text}${row.deviceName}设备吗？`)
        .then(() => {
          if (row.deviceState === 'notActive') {
            deployDevice(row.id).then(() => {
              this.handleRefresh()
            })
          } else {
            undeployDevice(row.id).then(() => {
              this.handleRefresh()
            })
          }
        }).then(() => {
        this.$modal.msgSuccess(`${text}成功`)
      })
    },

    /** 订阅设备状态（在线）实时数据 */
    subDeviceOnlineMessageAll() {
      this.socket.send({
        method: 'event',
        params: {
          subEvent: 'sub',
          content: {
            type: 'sub',
            id: 'device-online-message-all',
            // parameter: {},
            topic: '/device/*/*/online'
          }
        }
      }).then(data => {
        const payload = data.payload || {}
        const deviceId = payload.deviceId
        const messageType = payload.messageType
        this.updateDeviceState(deviceId, messageType)
      })
    },

    /** 取消设备状态（在线）实时数据订阅 */
    unsubDeviceOnlineMessageAll() {
      this.socket.send({
        method: 'event',
        params: {
          subEvent: 'unsub',
          content: {
            type: 'unsub',
            id: 'device-online-message-all',
          }
        }
      })
    },

    /** 订阅设备状态（离线）实时数据 */
    subDeviceOfflineMessageAll() {
      this.socket.send({
        method: 'event',
        params: {
          subEvent: 'sub',
          content: {
            type: 'sub',
            id: 'device-offline-message-all',
            // parameter: {},
            topic: '/device/*/*/offline'
          }
        }
      }).then(data => {
        const payload = data.payload || {}
        const deviceId = payload.deviceId
        const messageType = payload.messageType
        this.updateDeviceState(deviceId, messageType)
      })
    },

    /** 取消设备状态（离线）实时数据订阅 */
    unsubDeviceOfflineMessageAll() {
      this.socket.send({
        method: 'event',
        params: {
          subEvent: 'unsub',
          content: {
            type: 'unsub',
            id: 'device-offline-message-all',
          }
        }
      })
    },

    /** 更新设备状态 */
    updateDeviceState(deviceId, type) {

      if (!deviceId) {
        return
      }

      const index = this.deviceList.findIndex(data => data.id === deviceId)

      if (index === -1) {
        return
      }

      // 更新离线数
      this.updateOfflineCount()
      // 更新在线数
      this.updateOnlineCount()
      // 更新未激活设备数据量
      this.updateNotActiveCount()

      let row = this.deviceList[index]

      if (type === 'ONLINE') {
        row.deviceState = 'online'
        this.$set(this.deviceList, index, row)
      } else if (type === 'OFFLINE') {
        row.deviceState = 'offline'
        this.$set(this.deviceList, index, row)
      }

      // 更新详情页面状态
      if (deviceId === this.deviceDetailInfo.id) {
        this.$set(this.deviceDetailInfo, 'state', {
          'text': row.deviceState === 'online' ? '在线' : '离线',
          'value': row.deviceState
        })
      }
      // 在线状态提交到 DEVICE_ONLINE_CHANGE
      this.$store.commit('DEVICE_ONLINE_CHANGE', {
        deviceId,
        type
      })

    }

  }
}
</script>

<style lang="scss" scoped>

  .bg-purple {
    background: #f8f8f8;
    text-align: center;
    line-height: 30px;
    height: 30px
  }

  .bg-purple-light {
    background: #f4f4f5;
    text-align: center;
    line-height: 30px;
    height: 30px
  }

  .grid-content {
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    border-radius: 0;
    min-height: 40px;
    text-align: center;
  }

  .row-bg {
    text-align: center;
    padding: -10 0;
    background-color: #f4f4f5;
  }

  // 设备状态
  .device-state {
    color: #00000073
  }

</style>
